package com.shuan;

// Agent.java

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.ProtectionDomain;

public class DecryptionAgent {
    /**
     * 简单验证类文件格式（检查魔数 0xCAFEBABE）
     */
    private static boolean isValidClassFormat(byte[] classBytes) {
        if (classBytes == null || classBytes.length < 4) {
            return false;
        }
        // Java 类文件的魔数是前4字节：0xCAFEBABE
        return (classBytes[0] & 0xFF) == 0xCA
            && (classBytes[1] & 0xFF) == 0xFE
            && (classBytes[2] & 0xFF) == 0xBA
            && (classBytes[3] & 0xFF) == 0xBE;
    }
    // Agent 启动时调用（JVM 启动参数 -javaagent:xxx.jar）
    public static void premain(String agentArgs, Instrumentation inst) {
        //System.out.println("SpringBoot监控Agent已启动...");
        // 注册类文件转换器
        inst.addTransformer(new ClassFileTransformer() {
            @Override
            public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
                ProtectionDomain protectionDomain, byte[] classfileBuffer) {
                System.err.println("正在处理类:" + className);
                // 仅处理需要解密的类（示例：包路径为 com.example 的类）
                if (className.startsWith("com/shuan/modules/service/")) {
                    try {
                        System.err.println(className);
                        // 解密字节码（假设加密后的类已预先生成并存储）
                        // 注意：实际场景中，加密类可能动态获取（如从数据库/远程服务器）
                        byte[] encryptedBytes = getEncryptedBytes(className);
                        byte[] decryptedBytes = Decryptor.decrypt(encryptedBytes);
                        // 5. 验证解密后的字节码是否合法（可选，但推荐）
                        if (!isValidClassFormat(decryptedBytes)) {
                            System.err.println("[DecryptionAgent] 解密后字节码格式无效，使用原始字节码");
                            return classfileBuffer;
                        }
                        // 返回解密后的字节码（JVM 会加载此字节码）
                        return decryptedBytes;
                    } catch (Exception e) {
                        e.printStackTrace();
                        return null; // 解密失败，使用原始字节码（可能导致错误）
                    }
                }
                // 非目标类直接返回原始字节码
                return classfileBuffer;
            }

            // 模拟从文件/数据库获取加密字节码（需根据实际存储方式调整）
            private byte[] getEncryptedBytes(String className) throws Exception {
                // 示例：从本地文件读取加密字节码（路径需与加密时一致）
                //String encryptedPath = "encrypted/" + className.replace('/', '/') + ".enc";
                return Files.readAllBytes(Paths.get(className));
            }
        }, true);
    }
}